#ifndef MUCMAS_CORE_INC_BT_H
#define MUCMAS_CORE_INC_BT_H

#include <stdint.h>
#include "gpio.h"

// 防止按键抖动的确认时间, 用于短按事件
#define BT_JIT_TIME 10
// 按键按下等待同一组其他按键按下的时间, 用于同时按下多个键的事件
#define BT_WAIT_TIME 200
// 长按时间, 用于长按事件
#define BT_LONG_TIME 700

// 用于bu的常量宏
#define BU_M 0x001F // moment state: 按键状态
#define BU_C 0x03E0 // cache: 按键缓存
#define BU_S 0x7C00 // state: 去抖后的按键状态
#define BU_R 0x8000 // 一个剩下的bit, 空置

#define BU_M_M 0x0001
#define BU_M_U 0x0002
#define BU_M_D 0x0004
#define BU_M_L 0x0008
#define BU_M_R 0x0010

#define BU_C_M 0x0020
#define BU_C_U 0x0040
#define BU_C_D 0x0080
#define BU_C_L 0x0100
#define BU_C_R 0x0200

#define BU_S_M 0x0400
#define BU_S_U 0x0800
#define BU_S_D 0x1000
#define BU_S_L 0x2000
#define BU_S_R 0x4000

// 用于hist的常量宏
#define HIST_N 0x00 // 0000
#define HIST_J 0x01 // 0001
#define HIST_W 0x02 // 0010
#define HIST_L 0x04 // 0100
#define HIST_O 0x08 // 1000

typedef struct {
  // 总时间和各个按键更新的时刻
  struct{
  uint32_t m; // M键上次按下的时刻
  uint32_t u; // U键上次按下的时刻
  uint32_t d; // D键上次按下的时刻
  uint32_t l; // L键上次按下的时刻
  uint32_t r; // R键上次按下的时刻
  uint32_t lp; // 长按的上一次执行时刻
  uint32_t now; // 当前时间
  }time;
  // 长按的执行速度, 即相邻两次长按任务间隔的时间
  uint32_t speed;
  // 包含所有任务的列表
  struct{
    void (*M_L)(void*); void (*M_W)(void*);
    void (*M_J)(void*); void (*M_O)(void*); // M
    void (*U_L)(void*); void (*U_W)(void*);
    void (*U_J)(void*); void (*U_O)(void*); // U
    void (*D_L)(void*); void (*D_W)(void*);
    void (*D_J)(void*); void (*D_O)(void*); // D
    void (*L_L)(void*); void (*L_W)(void*);
    void (*L_J)(void*); void (*L_O)(void*); // L
    void (*R_L)(void*); void (*R_W)(void*);
    void (*R_J)(void*); void (*R_O)(void*); // R
  } task;
  // 按键状态, 分为M区, C区, S区
  uint16_t bu;
  // 记录上一次执行的任务类型
  struct{
    uint8_t hist : 4;
    uint8_t      : 4;
  };
}Bt_HandleTypeDef;

extern Bt_HandleTypeDef hbt;

void Bt_Init(
  void M_L(void*), void M_W(void*), void M_J(void*),
  void M_O(void*),  // M
  void U_L(void*), void U_W(void*), void U_J(void*),
  void U_O(void*),  // U
  void D_L(void*), void D_W(void*), void D_J(void*),
  void D_O(void*),  // D
  void L_L(void*), void L_W(void*), void L_J(void*),
  void L_O(void*),  // L
  void R_L(void*), void R_W(void*), void R_J(void*),
  void R_O(void*),  // R
  uint32_t speed
);
void Bt_Reinit(
  void M_L(void*), void M_W(void*), void M_J(void*),
  void M_O(void*),  // M
  void U_L(void*), void U_W(void*), void U_J(void*),
  void U_O(void*),  // U
  void D_L(void*), void D_W(void*), void D_J(void*),
  void D_O(void*),  // D
  void L_L(void*), void L_W(void*), void L_J(void*),
  void L_O(void*),  // L
  void R_L(void*), void R_W(void*), void R_J(void*),
  void R_O(void*),  // R
  uint32_t speed
);

void Bt_Update(void);

void Bt_Run(void* /*不是Bt_HandleTypeDef, 而是相应页面的handle*/);

#endif
